package cn.jeasy.core.bean;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.inject.Named;

import cn.jeasy.core.bean.annotation.Bean;
import cn.jeasy.core.bean.annotation.Component;
import cn.jeasy.core.bean.annotation.Repository;
import cn.jeasy.core.bean.annotation.Service;
import cn.jeasy.core.bean.support.ClassScanner;
import cn.jeasy.core.mvc.annotation.Controller;
import cn.jeasy.core.util.CollectionUtil;
import cn.jeasy.core.util.StringUtil;



/**
 * 实现 BeanDefinitionReader 接口的抽象类（未具体实现 loadBeanDefinitions，而是规范了
 *  BeanDefinitionReader 的基本结构）
 */
public  class DefaultBeanDefinitionReader{

	/**
	 *  通过String - beanDefinition 键值对保存IoC容器里的类定义。
	 */
	private Map<String, BeanDefinition> registry=new ConcurrentHashMap<String, BeanDefinition>() ;

    public Map<String, BeanDefinition> getRegistry() {
        return registry;
    }
    
	/**
	 * 扫描指定包下的class来注册bean
	 * @param packageName
	 * @throws IOException 
	 */
    @SuppressWarnings("unchecked")
	public void loadBeanDefinitionsByPackage(String packageName) throws Exception{
				
		List<Class<?>>  classList=ClassScanner.getInstance().getClassListByAnnotations(packageName,
				new Class[]{Bean.class,Named.class,Service.class,Repository.class,Component.class});
		if(CollectionUtil.isEmpty(classList))return;
		for(Class<?> clazz:classList){
			registryClass(clazz);
		}
	}
    
    /**
	 * 注册class至bean容器
	 * @param clazz
	 */
	public void registryClass(Class<?> clazz){
		BeanDefinition beanDefinition = new BeanDefinition();	
		String beanName=StringUtil.firstToLower(clazz.getSimpleName());
		
		if(clazz.isAnnotationPresent(Named.class)){
			Named n=clazz.getAnnotation(Named.class);
			if(StringUtil.isNotEmpty(n.value())) beanName=n.value();
			
		}else if(clazz.isAnnotationPresent(Service.class)){
			Service s=clazz.getAnnotation(Service.class);
			if(StringUtil.isNotEmpty(s.value())) beanName=s.value();
			
		}else if(clazz.isAnnotationPresent(Repository.class)){
			Repository r=clazz.getAnnotation(Repository.class);
			if(StringUtil.isNotEmpty(r.value())) beanName=r.value();
			
		}else if(clazz.isAnnotationPresent(Component.class)){
			Component c=clazz.getAnnotation(Component.class);
			if(StringUtil.isNotEmpty(c.value())) beanName=c.value();
			
		}else if(clazz.isAnnotationPresent(Controller.class)){
			Controller c=clazz.getAnnotation(Controller.class);
			if(StringUtil.isNotEmpty(c.value())) beanName=c.value();
			
		}else if(clazz.isAnnotationPresent(Bean.class)){
			Bean c=clazz.getAnnotation(Bean.class);
			if(StringUtil.isNotEmpty(c.value())) beanName=c.value();
		}
		
		// 设置className的同时，也在内部设置了Class					
		beanDefinition.setBeanClass(clazz);
		// 注册类定义
		registry.put(beanName, beanDefinition);
	}
    
}
